﻿#ifndef AUDIO_PROCESSOR_H
#define AUDIO_PROCESSOR_H

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/audio_fifo.h>
#include <libavutil/channel_layout.h>
#include <libavutil/opt.h>
#include <libswresample/swresample.h>
}

#include <queue>
#include <string>
#include <vector>

enum class AudioFormat {
    FLAC,
    AAC
};

class AudioProcessor {
public:
    void clear();
    void generate(
        std::string audio_input_path,
        AudioFormat using_aac,
        double delay_secs,
        int sample_rate,
        int aac_bit_rate,
        int flac_bit_width,
        int flac_compression_level
    );
    std::queue<std::pair<AVPacket, int64_t>> get_packets();
    bool has_packet() const;
    int sample_rate() const;
    void set_stream(AVStream* audio_stream, AVFormatContext* fmt_ctx);

private:
    void _encode_frame(AVCodecContext* dec_ctx, AVFrame* frame, AVFrame* swr_frame, AVFrame* enc_frame, int64_t& current_pts, AVAudioFifo* fifo, AVPacket* enc_pkt, int& ret);
    void _open_audio(std::string audio_input_path);
    void _set_aac_codec(int sample_rate, int bit_rate);
    void _set_flac_codec(int flac_bit_width, int flac_sample_rate, int flac_compression_level);
    void _set_resampler();
    void _convert_audio(double delay_secs, int flac_sample_rate);

    AVCodecContext* codec_ctx;
    AVCodecParameters* audio_codecpar;
    AVFormatContext *audio_input_ctx = NULL;
    SwrContext* swr_ctx;
    std::queue<std::pair<AVPacket, int64_t>> audio_packet_queue;
    int audio_stream_index;
    bool _has_packet = false;
};

#endif